package io.red;

import io.Archivo;
import io.Carpeta;
import io.Cliente;
import io.Mensaje;
import io.Procesador;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.net.Socket;
import java.nio.channels.ClosedByInterruptException;

/**
 *
 * @author Mariano Zapata
 */
public class Conexion extends Thread {
    
    private Socket conexionObjeto;
    private Socket conexionArchivo;
    private ObjectInputStream entradaObjeto;
    private ObjectOutputStream salidaObjeto;
    private BufferedInputStream entradaArchivo;
    private BufferedOutputStream salidaArchivo;
    private boolean vida;
    private int id;
    private Procesador procesador;
    
    private static final int TAMANIO_BUFFER= 1024;
    
    public Conexion(Socket conexionObjeto, Socket conexionArchivo) throws IOException
    {
        super();
        procesador= null;
        id= -1;
        vida= true;
        this.conexionObjeto= conexionObjeto;
        this.conexionArchivo= conexionArchivo;
        entradaObjeto= new ObjectInputStream(this.conexionObjeto.getInputStream());
        salidaObjeto= new ObjectOutputStream(this.conexionObjeto.getOutputStream());
        entradaArchivo= new BufferedInputStream(this.conexionArchivo.getInputStream());
        salidaArchivo= new BufferedOutputStream(this.conexionArchivo.getOutputStream());
    }
    
    @Override
    public void run()
    {
        while (vida)
        {
            try {
                Mensaje msj= (Mensaje) entradaObjeto.readObject();
                msj.asignarDuenio(id);
                procesador.procesar(msj);
            } catch (IOException ex) {vida= false;
                                      if (!(ex instanceof ClosedByInterruptException))
                                      {
                                          try {
                                              procesador.quitarConexion(this);
                                              conexionObjeto.close();
                                              conexionArchivo.close();
                                          } catch (InterruptedException exx) {/*NADA*/}
                                            catch (IOException exx) {/*NADA */}
                                      }
                                     }
              catch (ClassNotFoundException ex) {/*NADA*/}
        }
    }
    
    public void enviar(Mensaje msj)
    {
        try {
            
            Carpeta resp= (Carpeta) msj.obtenerCargaUtil();
            for (Carpeta c : resp.getHijosCarpeta())
                System.out.println(c.getNombre());
            for (Cliente l : resp.getHijosCliente())
                System.out.println(l.getApellido());
            for (Archivo a : resp.getHijosArchivo())
                System.out.println(a.getNombre());
            
            salidaObjeto.writeObject(msj);
            salidaObjeto.flush();
        } catch (IOException ex) {/*NADA*/}
    }
    
    public void enviar(InputStream is)
    {
        byte [] buffer= new byte[TAMANIO_BUFFER];
        int n= -1;
        try {
            while ((n= is.read(buffer)) > -1)
                salidaArchivo.write(buffer, 0, n);
        } catch (IOException ex) {/*NADA*/}
          finally {try {
                        is.close();
                   } catch (IOException ex) {/*NADA*/}
}
    }
    
    public InputStream obtenerEntradaArchivo() {return entradaArchivo;}
    
    public void asignarId(int id)
    {
        this.id= id;
        super.setName("Conexión_" + id);
    }
    
    public int obtenerId() {return id;}
    
    public void asignarProcesador(Procesador procesador) {this.procesador= procesador;}
    
    @Override
    public boolean equals(Object obj) {
        if (obj == null) {
            return false;
        }
        if (getClass() != obj.getClass()) {
            return false;
        }
        final Conexion other = (Conexion) obj;
        if (this.id != other.id) {
            return false;
        }
        return true;
    }

    @Override
    public int hashCode() {
        int hash = 7;
        hash = 53 * hash + this.id;
        return hash;
    }
}
